#!/bin/bash
# 把访问量比较大的IP段封掉，同时解封之前封禁的IP，并重新循环
# 定义5分钟以前的时间，用于过滤5分钟以前的日志
start_time=$(date -d "-5 minutes" "+%d/%b/%Y:%H:%M")
end_time=$(date "+%d/%b/%Y:%H:%M")
log="/tmp/health.sina.cn_ip_block.log"
blocked_ips="/etc/nginx/blockips_new.conf"

block_ip() {
    # 截取5分钟以前至当前的日志
    awk -v start="$start_time" -v end="$end_time" -F '[][]' '$2 >= start && $2 <= end' "$log" >/tmp/tmp_last_minute.log
    # 将所有ip都过滤出来，存到临时文件
    awk '{print $1}' /tmp/tmp_last_minute.log >/tmp/tmp_last_minute_ip.log

    # 处理IP，只留前面三位，排序、去重，获取多于1500次请求的ip段，这个数字可以根据实际情况来调整
    awk -F '.' '{print $1"."$2"."$3"."}' /tmp/tmp_last_minute_ip.log | sort | uniq -c | sort -n | awk '$1 > 1500 {print $2}' >/tmp/bad_ip_minute.list

    # 当ip数大于0时，才会将它写入到封禁IP文件中
    ip_n=$(wc -l /tmp/bad_ip_minute.list | awk '{print $1}')
    if [ ${ip_n} -ne 0 ]; then
        cat /dev/null >"$blocked_ips"
        for ip in $(cat /tmp/bad_ip_minute.list); do
            # 封ip，不能直接封ip段
            for ip2 in $(grep "^$ip" /tmp/tmp_last_minute_ip.log | sort -n | uniq); do
                echo "deny $ip2;" >>"$blocked_ips"
            done
        done
        echo "allow all;" >>"$blocked_ips"
    fi

    ngins_status=$(/usr/sbin/nginx -t)
    if [ $? -eq 0 ]; then
        # 重新加载nginx
        /usr/sbin/nginx -s reload
    fi
}

# 检查命令行参数
if [[ $# -ne 1 ]]; then
    echo "请输入参数：start"
    exit 1
fi

# 根据命令行参数调用相应的函数
if [[ $1 == "start" ]]; then
    block_ip
else
    echo "参数输入错误。"
    exit 1
fi
